package org.stimuliband.microphone;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.TargetDataLine;

/**
 *
 */
public class MicrophoneObserverable implements Runnable {

    // how many bits per sample?
    final static int SAMPLE_BITS = 8;
    // how many channels ? 1 is MONO
    final static int CHANNELS = 1;
    // amount of probes in group
    final int probesGroupSize;
    // sound input line
    final TargetDataLine line;
    // listeners of probes from microphone
    final MicrophoneListener listener;
    // kontekst
    volatile boolean working = true;

    public MicrophoneObserverable(int samplingRate, int probesGroupSize, MicrophoneListener listener) throws LineUnavailableException {
        this.probesGroupSize = probesGroupSize;
        this.listener = listener;

        // initialization of microphone
        AudioFormat gsm = new AudioFormat(samplingRate, SAMPLE_BITS, CHANNELS, true, true);
        DataLine.Info info = new DataLine.Info(TargetDataLine.class, gsm);
        if (!AudioSystem.isLineSupported(info)) {
            throw new IllegalArgumentException("This audio format is not supported");
        }
        this.line = (TargetDataLine) AudioSystem.getLine(info);
    }

    public void start() throws LineUnavailableException {
        line.open();
        line.start();
        working = true;
    }

    public void stop() {
        line.stop();
        line.close();
        working = false;
    }

    @Override
    public void run() {
        byte[] captured = new byte[probesGroupSize];
        int size = 0;
        while (working) {
            size = line.read(captured, 0, captured.length);
            if (size == probesGroupSize) {
                listener.onCaptured(captured);
            }
        }
    }
}
